package com.xuecheng.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.mysql.jdbc.StringUtils;
import com.xuecheng.commons.constants.OrdersConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.RecordDto;
import com.xuecheng.commons.model.vo.AuthInfo;
import com.xuecheng.commons.model.vo.CoursePubIndexVo;
import com.xuecheng.commons.model.vo.OrdersVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.learning.api.LearningClient;
import com.xuecheng.order.config.PayTemplate;
import com.xuecheng.order.domain.Orders;
import com.xuecheng.order.domain.Payment;
import com.xuecheng.order.mapper.OrdersMapper;
import com.xuecheng.order.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.order.service.PaymentService;
import com.xuecheng.search.api.SearchClient;
import com.xuecheng.web.exception.BusinessException;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-12-13
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
    @Autowired
    private SearchClient searchClient;
    @Autowired
    private PayTemplate payTemplate;
    //用户下单购买课程 生成订单
    @Override
    public ResponseResult<String> creatOrder(Long coursePubId) {
        //通过tl获取用户id
        Long userId = AuthInfoHolder.getUserId();
        //判断此用户是否已下单已购买（生成订单已支付）
        Long count = this.lambdaQuery()
                .eq(Orders::getCoursePubId, coursePubId)
                .eq(Orders::getUserId, userId)
                .eq(Orders::getStatus, OrdersConstants.ORDER_PAID_STATUS).count();
        if (count>0) {
            throw new BusinessException(ErrorCode.ORDERERROR);
        }
        //判断此用户是否已下单未购买（生成订单未支付）
        Orders one = this.lambdaQuery()
                .eq(Orders::getCoursePubId, coursePubId)
                .eq(Orders::getUserId, userId)
                .eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS).one();
        if (one!=null) {
            return ResponseResult.okResult(one.getOrderNo());
        }
        //如果未生成订单——》 生成一个新订单
        Orders orders = new Orders();
        //封装新订单需要课程计划参数  先查询课程计划对象  feign
        ResponseResult<CoursePubIndexVo> responseResult = searchClient.findById(coursePubId.toString());
        if (responseResult.getCode()!=0) {
            throw new BusinessException(ErrorCode.PAYERROR);
        }
        CoursePubIndexVo pubIndexVo = responseResult.getData();
        orders.setOrderNo(IdUtil.simpleUUID());// 32位UUID
        orders.setCoursePubId(pubIndexVo.getCourseId());// 课程id
        orders.setCoursePubName(pubIndexVo.getName());// 课程名称
        orders.setCompanyId(pubIndexVo.getCompanyId()); // 机构id
        orders.setCompanyName(pubIndexVo.getCompanyName());// 机构名称
        orders.setUserId(userId);// 用户id
        orders.setPrice(pubIndexVo.getPrice().longValue());// 订单价格，单位分
        orders.setStatus(OrdersConstants.ORDER_INIT_STATUS); // 订单状态未支付
        orders.setCreateDate(new Date()); // 下单时间
        // 5.保存订单
        this.save(orders);
        // 6.返回订单号
        return ResponseResult.okResult(orders.getOrderNo());
    }
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private LearningClient learningClient;
    // 查询支付结果
    @GlobalTransactional
    @Override
    public ResponseResult<OrdersVo> isPay(String orderNo) {
        // 1.查询微信支付状态
        Boolean checkPayment = payTemplate.checkPayment(orderNo);
        // 2.未支付
        if (checkPayment==false) {
            throw new BusinessException(ErrorCode.NOTPLAY);
        }
        // 3.已支付
        // 3-1 查询订单
        Orders orders = this.lambdaQuery()
                .eq(Orders::getOrderNo, orderNo)
                .one();
        // 3-2 判断订单状态
        if (orders.getStatus().equals(OrdersConstants.ORDER_INIT_STATUS)) {
            // 调用方法更新订单、明细、选课记录
            updatePayStatus(orderNo, orders);
        }
        // 4.订单转vo
        OrdersVo vo = BeanHelper.copyProperties(orders, OrdersVo.class);
        // 5.返回vo
        return ResponseResult.okResult(vo);
    }
    //定时清理未支付订单
    @Override
    public void clearOrder() {
        //查询15分钟前未支付订单
        //获取15分钟前时间
        String oldTime = DateUtil.offsetMinute(new Date(), -15).toString();
        //通过未支付状态和小于下单时间查询数据库
        List<Orders> list = this.lambdaQuery()
                .eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS)
                .lt(Orders::getCreateDate, oldTime)
                .list();
        //遍历这个集合
        if (CollectionUtil.isNotEmpty(list)){
        for (Orders orders : list) {
            //再次判断有没有付款 向微信查询（避免卡点付款）
            Boolean aBoolean = payTemplate.checkPayment(orders.getOrderNo());
            if (aBoolean==false){
                //用户未付款 清理
                //微信关闭订单
                payTemplate.closeOrder(orders.getOrderNo());
                //数据库也修改订单状态
                orders.setStatus(OrdersConstants.ORDER_CLOSED_STATUS);
                this.updateById(orders);
            }else {//用户已付款
                //更新订单 明细状态 保存选课记录
                updatePayStatus(orders.getOrderNo(),orders);

            }


        }
        }else {
            System.out.println("没有超时订单");
        }
    }

    // 抽取更新订单状态
    private void updatePayStatus(String orderNo, Orders orders) {
        // 更新订单
        orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
        this.updateById(orders);
        // 更新订单明细
        paymentService.lambdaUpdate()
                .set(Payment::getStatus,"1")
                .eq(Payment::getOrderNo, orderNo)
                .update();

        // 保存选课记录
        RecordDto recordDto = new RecordDto();
        recordDto.setUserId(orders.getUserId()); // 用户id
        recordDto.setCoursePubId(orders.getCoursePubId()); // 课程id
        ResponseResult responseResult = learningClient.saveRecord(recordDto);
     /*   //判断结果是否为空        if (responseResult.getCode()!=0){
            throw new BusinessException(ErrorCode.NOTFOUND);
        }*/
    }
}
